package com.shigu.user.service;

import com.opentae.data.mall.beans.MallWallet;
import com.opentae.data.mall.beans.ManagerMallUser;
import com.opentae.data.mall.beans.UserInviteInfo;
import com.opentae.data.mall.beans.UserWxInfo;
import com.opentae.data.mall.examples.ManagerMallUserExample;
import com.opentae.data.mall.interfaces.*;
import com.shigu.MallResponse;
import com.shigu.account.api.VipManagerService;
import com.shigu.account.enums.MoneyRecordType;
import com.shigu.account.enums.UserType;
import com.shigu.account.enums.VipLevel;
import com.shigu.account.service.UserAccountService;
import com.shigu.appVersion.service.VersionService;
import com.shigu.constant.enums.PageUri;
import com.shigu.constant.enums.SystemConstant;
import com.shigu.constant.enums.VipConstant;
import com.shigu.constant.service.SystemConstantService;
import com.shigu.exceptions.WapException;
import com.shigu.paypwd.util.MD5Util;
import com.shigu.phoneCode.enums.PhoneCodeType;
import com.shigu.phoneCode.service.PhoneCodeService;
import com.shigu.trade.service.TradeService;
import com.shigu.user.OSS.OssIO;
import com.shigu.user.vo.AppUserResponse;
import com.shigu.user.vo.XcxLoginResponse;
import com.shigu.weixin.exceptions.UtilsException;
import com.shigu.weixin.service.WxUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
public class AppLoginService {
    @Autowired
    ManagerMallUserMapper managerMallUserMapper;
    @Autowired
    UserAccountService userAccountService;
    @Autowired
    PhoneCodeService phoneCodeService;
    @Autowired
    OssIO ossIO;
    @Autowired
    ValidCodeMapper validCodeMapper;
    @Autowired
    MallWalletMapper mallWalletMapper;
    @Autowired
    WxUserService wxUserService;
    @Autowired
    TradeService tradeService;
    @Autowired
    MallTokenService mallTokenService;

    @Autowired
    MallWalletRecordMapper mallWalletRecordMapper;
    @Autowired
    MallTradeMapper mallTradeMapper;
    @Autowired
    MallOrderMapper mallOrderMapper;
    @Autowired
    MallOrderLogisticsMapper mallOrderLogisticsMapper;
    @Autowired
    UserWxInfoMapper userWxInfoMapper;

    @Resource(name = "vipManagerServiceImpl")
    VipManagerService vipManagerService;
    @Autowired
    UserInviteInfoMapper userInviteInfoMapper;
    @Autowired
    SystemConstantService systemConstantService;
    @Autowired
    VersionService versionService;

    /**
     * @return 返回用户id
     * @description 注册并完善信息
     * @author 郭尔
     * @date 2019/2/13 15:48
     */
    public synchronized Long userRegister(String username, String telephone, String password, String imgData,String inviteCode,String version,String os) throws WapException, IOException {

        //验证用户名是否已存在
        ManagerMallUserExample example = new ManagerMallUserExample();
        example.createCriteria().andNickEqualTo(username);
        int count = managerMallUserMapper.countByExample(example);
        if (count > 0) {
            throw new WapException("该用户名已被占用");
        }
        //校验邀请码是否正确
        Long agnetId = vipManagerService.codeToUser(inviteCode);
        if(agnetId == null || agnetId.longValue() == 0L){
            throw new WapException("不存在的邀请码");
        }
        Integer agent = userInviteInfoMapper.userLevel(agnetId);
        if (agent== null){
            throw new WapException("不存在的邀请码");
        }
        //判断邀请用户等级
        if (agent.equals( VipLevel.COMMON.getValue())) {
           // 为普通用户
            throw new WapException("无效的邀请码");
        }

        String imgUrl = uploadImgToOSS(imgData);
        ManagerMallUser user = new ManagerMallUser();
        user.setNick(username);
        user.setLoginName(telephone);
        user.setPassword(MD5Util.md5(password));
        user.setHeadUrl(imgUrl);
        user.setCreateTime(new Date());
        user.setUserType(UserType.APP.getValue());
        managerMallUserMapper.insertSelective(user);

        MallWallet wallet = new MallWallet();
        wallet.setUserId(user.getMallUserId());
        wallet.setMallMoney(0d);
        mallWalletMapper.insertSelective(wallet);

        UserInviteInfo info = new UserInviteInfo();
        info.setMallUserId(user.getMallUserId());
        info.setAgentId(agnetId);
        userInviteInfoMapper.insertSelective(info);
        String uri = versionService.versionUri(version, os);
        Map<String, String> map = systemConstantService.selPageConstant(uri);
        int lv = Integer.valueOf(map.get(VipConstant.defaultLv.toString()));

        vipManagerService.changeUserLevel(user.getMallUserId(), lv);
        //推荐人的邀请人加1
        userInviteInfoMapper.changeInviteNum(agnetId,1);

        return user.getMallUserId();
    }

    /**
     * @description 登陆
     * @author 郭尔
     * @date 2019/2/13 16:39
     */
    public Long pwdLogin(String username, String password,String cid) throws WapException {
        ManagerMallUser user = managerMallUserMapper.selUserByName(username);
        if (user == null) {
            throw new WapException("用户不存在");
        }
        if (!user.getPassword().equals(MD5Util.md5(password))) {
            throw new WapException("密码错误");
        }
        if(StringUtils.isNotBlank(cid)){
            UserInviteInfo info = new UserInviteInfo();
            info.setMallUserId(user.getMallUserId());
            info.setDeviceCid(cid);
            userInviteInfoMapper.updateByPrimaryKeySelective(info);
        }

        return user.getMallUserId();
    }

    /**
     * @description 发送注册验证码
     * @author 郭尔
     * @date 2019/2/14 15:52
     */
    public MallResponse registeCode(String telephone) throws WapException {
        //判断是否已注册
        ManagerMallUserExample example = new ManagerMallUserExample();
        example.createCriteria().andLoginNameEqualTo(telephone);
        int count = managerMallUserMapper.countByExample(example);
        if (count > 0) {
            throw new WapException("该手机号已注册");
        }
        phoneCodeService.sendCode(telephone, PhoneCodeType.REGISTER.getValue());
        return new MallResponse().success();
    }

    /**
     * @description 修改密码
     * @author 郭尔
     * @date 2019/2/15 14:50
     */
    public MallResponse modPwdCode(String telephone) throws WapException {
        //判断是否已注册
        ManagerMallUserExample example = new ManagerMallUserExample();
        example.createCriteria().andLoginNameEqualTo(telephone);
        List<ManagerMallUser> list = managerMallUserMapper.selectByExample(example);
        if (list.size() < 1) {
            throw new WapException("该手机号未注册");
        }
        phoneCodeService.sendCode(telephone, PhoneCodeType.PASSWORD.getValue());
        return new MallResponse().success();
    }

    /**
     * @description 根据手机号修改密码
     * @author 郭尔
     * @date 2019/2/15 15:16
     */
    public Long modPwd(String telephone, String newPassword) {
        ManagerMallUser user = managerMallUserMapper.selUserByName(telephone);
        user.setPassword(MD5Util.md5(newPassword));
        managerMallUserMapper.updateByPrimaryKeySelective(user);
        return user.getMallUserId();
    }

    /**
     * @description 上传图片到oss
     * @author 郭尔
     * @date 2019/2/16 14:17
     *
     */
    public String uploadImgToOSS(String mayBeBase64) throws IOException {
        if (StringUtils.isNotEmpty(mayBeBase64) && !mayBeBase64.startsWith("http")) {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes = decoder.decodeBuffer(mayBeBase64);
            Random random = new Random();
            String filename = "app/mall/head/" + random.nextInt(20000) + System.currentTimeMillis() + ".jpg";
            return ossIO.uploadFile(bytes, filename);
        }
        return mayBeBase64;
    }

    /**
     * @description 获取用户信息
     * @author 郭尔
     * @date 2019/2/16 15:45
     */
    public AppUserResponse getAppUser(Long userId) {
        AppUserResponse response = new AppUserResponse();
        ManagerMallUser user = managerMallUserMapper.selectByPrimaryKey(userId);

        DecimalFormat df = new DecimalFormat("LZ000000");
        if (StringUtils.isNotBlank(user.getLoginName())) {
            // 小程序外的用户 loginName即为手机号
            response.setTelephone(user.getLoginName());
        }
        Map<String, String> map = systemConstantService.selPageConstant(PageUri.system.toString());

        response.setUserId(df.format(user.getMallUserId()));
        response.setNick(user.getNick());
        String headUrl = StringUtils.isNotBlank(user.getHeadUrl())?user.getHeadUrl():map.get(SystemConstant.defaultHeadUrl.toString());
        response.setHeaderUrl(headUrl);

        //微信昵称
        UserWxInfo info = userWxInfoMapper.selectFieldsByPrimaryKey(userId, "wx_nick");
        if(info!=null){
            response.setWxUserName(info.getWxNick());
        }
        Integer level = userInviteInfoMapper.userLevel(userId);
        response.setUserType(level);
        return response.success();
    }

    /**
     * @description 修改用户头像
     * @author 郭尔
     * @date 2019/2/14 17:55
     */
    public MallResponse changeHeadUrl(Long userId, String imgData) throws IOException {
        String imgUrl = uploadImgToOSS(imgData);
        ManagerMallUser user = new ManagerMallUser();
        user.setMallUserId(userId);
        user.setHeadUrl(imgUrl);
        managerMallUserMapper.updateByPrimaryKeySelective(user);
        return new MallResponse().success();
    }

    /**
     * @description 小程序登录
     * @author 郭尔
     * @date 2019/2/27 13:38
     */
    public XcxLoginResponse getWxLoginUser(String openIid, String headUrl, String nick, String unionId) {
        Long userId = wxUserService.wxAppLogin(openIid, headUrl, nick, unionId);
        //换成token
        String token = mallTokenService.userIdToToken(userId);
        XcxLoginResponse response = new XcxLoginResponse();
        response.setToken(token);
        DecimalFormat df = new DecimalFormat("LZ000000");
        response.setUserId(df.format(userId));
//        tradeService.clearTrade(userId);
        return response.success();
    }

    /**
     * @description 绑定
     * @author 郭尔
     * @date 2019-05-07 15:34
     */
    public synchronized MallResponse bindWxUser(String unionId, Long mallUserId, String wxNick,String openId,String avatarUrl) throws UtilsException {
        //原来的用户id
        Long oldId = wxUserService.appBindWx(mallUserId, unionId, wxNick,openId,avatarUrl);

        if (oldId != null) {
            //将原用户的余额转到app用户下
            MallWallet old = mallWalletMapper.selByUserId(oldId);
            if( old != null){
                if(old.getMallMoney()>0){
                    mallWalletMapper.changeTotal(mallUserId,old.getTotalReward());
                    //插入一条钱包记录
                    userAccountService.addMoney(mallUserId,old.getMallMoney(), MoneyRecordType.fromXcx.getText());
                }
                mallWalletMapper.deleteByPrimaryKey(old.getWalletId());
            }
            //删除小程序用户
            managerMallUserMapper.deleteByPrimaryKey(oldId);
        }
        return new MallResponse().success();
    }


    /**
     *
     * @description 网页端非填写的注册提交
     * @author 郭尔
     * @date 2019-11-19 14:07
     */
    public MallResponse submitRegist(String telephone,String password,String code) throws WapException {
        //校验邀请码是否正确
        Long agnetId = vipManagerService.codeToUser(code);
        if(agnetId == null || agnetId.equals(0L)){
            throw new WapException("注册失败，不合规则的邀请");
        }
        Integer agent = userInviteInfoMapper.userLevel(agnetId);
        if (agent == null){
            throw new WapException("注册失败，请联系邀请人");
        }
        //判断邀请用户等级
        if (agent.equals( VipLevel.COMMON.getValue())) {
            // 为普通用户
            throw new WapException("注册失败，邀请人权限失效");
        }
        ManagerMallUser user = new ManagerMallUser();
        user.setLoginName(telephone);
        user.setPassword(MD5Util.md5(password));
        user.setCreateTime(new Date());
        user.setUserType(UserType.APP.getValue());
        managerMallUserMapper.insertSelective(user);

        user.setNick("惠优品"+user.getMallUserId());
        managerMallUserMapper.updateByPrimaryKeySelective(user);

        MallWallet wallet = new MallWallet();
        wallet.setUserId(user.getMallUserId());
        wallet.setMallMoney(0d);
        mallWalletMapper.insertSelective(wallet);

        UserInviteInfo info = new UserInviteInfo();
        info.setMallUserId(user.getMallUserId());
        info.setVipLevel(1);
        info.setAgentId(agnetId);
        userInviteInfoMapper.insertSelective(info);
        //推荐人的邀请人加1
        userInviteInfoMapper.changeInviteNum(agnetId,1);

        return new MallResponse().success();
    }
}
